/***************************************************
 @Name :        小铭同学
 @Time :        2025-09-03
 @Email :       LiaoMingWJ233@163.com
 @Comment :     温湿度传感器 图表 控件类
 @FileName :    th_chart.cpp
 @Version :     1.0
****************************************************/


#include "th_chart.h"
#include <QDateTime>
#include <QDebug>
#include <cmath>
#include <QRandomGenerator>

#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif

TH_chart::TH_chart(QWidget *parent)
    : QWidget(parent)
{
    //qDebug() << "TH_chart constructor called";
    
    // 先初始化UI和图表
    initUI();
    initChart();
    
    // 然后创建定时器
    animationTimer = new QTimer(this);
    connect(animationTimer, &QTimer::timeout, this, &TH_chart::updateAnimation);
    animationTimer->start(50); // 降低到20FPS，减少CPU使用
    
    // 设置默认大小
    setFixedChartSize(400, 300);
    
    //qDebug() << "TH_chart constructor completed";
}

TH_chart::~TH_chart()
{
    //qDebug() << "TH_chart destructor called";
    cleanup();
}

void TH_chart::cleanup()
{
    // 安全地停止和删除定时器
    if (animationTimer) {
        animationTimer->stop();
        animationTimer->deleteLater();
        animationTimer = nullptr;
    }   
}

void TH_chart::initUI()
{
    //qDebug() << "Initializing UI";
    
    try {
        // 创建主布局
        QVBoxLayout *mainLayout = new QVBoxLayout(this);
        mainLayout->setContentsMargins(5, 5, 5, 5);
        mainLayout->setSpacing(5);
        
        // 创建数值显示标签
        QHBoxLayout *labelLayout = new QHBoxLayout();
        labelLayout->setSpacing(10);
        
        tempLabel = new QLabel("温度: 0.0 °C", this);
        tempLabel->setAlignment(Qt::AlignCenter);
        tempLabel->setMinimumWidth(120);
        tempLabel->setStyleSheet("QLabel { background-color: #FF6B6B; color: white; padding: 8px; border-radius: 8px; font-weight: bold; }");
        
        humidityLabel = new QLabel("湿度: 0.0 %", this);
        humidityLabel->setAlignment(Qt::AlignCenter);
        humidityLabel->setMinimumWidth(120);
        humidityLabel->setStyleSheet("QLabel { background-color: #4ECDC4; color: white; padding: 8px; border-radius: 8px; font-weight: bold; }");
        
        labelLayout->addWidget(tempLabel);
        labelLayout->addWidget(humidityLabel);
        labelLayout->setAlignment(Qt::AlignCenter);
        
        // 创建图表视图
        chartView = new QChartView(this);
        chartView->setRenderHint(QPainter::Antialiasing);
        
        // 添加到主布局
        mainLayout->addLayout(labelLayout);
        mainLayout->addWidget(chartView);
        
        setLayout(mainLayout);
        
        //qDebug() << "UI initialization completed";
    } catch (const std::exception &e) {
        //qCritical() << "UI initialization failed:" << e.what();
    }
}

void TH_chart::initChart()
{
    //qDebug() << "Initializing chart";
    
    try {
        // 创建图表
        chart = new QChart();
        chart->setTitle("温湿度监测");
        chart->setTheme(QChart::ChartThemeLight);
        chart->setAnimationOptions(QChart::SeriesAnimations);
        chart->setBackgroundVisible(false);
        
        // 创建温度系列
        tempSeries = new QLineSeries();
        tempSeries->setName("温度 (°C)");
        tempSeries->setColor(QColor("#FF6B6B"));
        tempSeries->setPen(QPen(QColor("#FF6B6B"), 2));
        
        // 创建湿度系列
        humiditySeries = new QLineSeries();
        humiditySeries->setName("湿度 (%)");
        humiditySeries->setColor(QColor("#4ECDC4"));
        humiditySeries->setPen(QPen(QColor("#4ECDC4"), 2));
        
        // 添加到图表
        chart->addSeries(tempSeries);
        chart->addSeries(humiditySeries);
        
        // 创建坐标轴
        axisX = new QValueAxis();
        axisX->setRange(0, MAX_DATA_POINTS);
        axisX->setLabelFormat("%d");
        axisX->setTitleText("时间点");
        axisX->setGridLineVisible(true);
        axisX->setGridLineColor(QColor(200, 200, 200, 100));
        
        axisYTemp = new QValueAxis();
        axisYTemp->setRange(tempMin, tempMax);
        axisYTemp->setTitleText("温度 (°C)");
        axisYTemp->setLinePenColor(QColor("#FF6B6B"));
        axisYTemp->setLabelsColor(QColor("#FF6B6B"));
        axisYTemp->setGridLineVisible(true);
        axisYTemp->setGridLineColor(QColor(255, 107, 107, 50));
        
        axisYHumidity = new QValueAxis();
        axisYHumidity->setRange(humidityMin, humidityMax);
        axisYHumidity->setTitleText("湿度 (%)");
        axisYHumidity->setLinePenColor(QColor("#4ECDC4"));
        axisYHumidity->setLabelsColor(QColor("#4ECDC4"));
        axisYHumidity->setGridLineVisible(true);
        axisYHumidity->setGridLineColor(QColor(78, 205, 196, 50));
        
        // 关联坐标轴
        chart->addAxis(axisX, Qt::AlignBottom);
        chart->addAxis(axisYTemp, Qt::AlignLeft);
        chart->addAxis(axisYHumidity, Qt::AlignRight);
        
        tempSeries->attachAxis(axisX);
        tempSeries->attachAxis(axisYTemp);
        humiditySeries->attachAxis(axisX);
        humiditySeries->attachAxis(axisYHumidity);
        
        // 设置图表到视图
        if (chartView) {
            chartView->setChart(chart);
        }
        
        //qDebug() << "Chart initialization completed";
    } catch (const std::exception &e) {
        qCritical() << "Chart initialization failed:" << e.what();
    }
}

void TH_chart::setTemperature(float temp)
{
    if (std::isnan(temp) || std::isinf(temp)) {
        qWarning() << "Invalid temperature value:" << temp;
        return;
    }
    
    currentTemp = temp;
    
    // 添加新数据点
    tempData.append(QPointF(tempData.size(), temp));
    
    // 保持数据点数量
    if (tempData.size() > MAX_DATA_POINTS) {
        tempData.removeFirst();
    }
    
    updateDisplay();
}

void TH_chart::setHumidity(float humidity)
{
    if (std::isnan(humidity) || std::isinf(humidity)) {
        qWarning() << "Invalid humidity value:" << humidity;
        return;
    }
    
    currentHumidity = humidity;
    
    // 添加新数据点
    humidityData.append(QPointF(humidityData.size(), humidity));
    
    // 保持数据点数量
    if (humidityData.size() > MAX_DATA_POINTS) {
        humidityData.removeFirst();
    }
    
    updateDisplay();
}

void TH_chart::setRange(float minTemp, float maxTemp, float minHumidity, float maxHumidity)
{
    tempMin = minTemp;
    tempMax = maxTemp;
    humidityMin = minHumidity;
    humidityMax = maxHumidity;
    
    if (axisYTemp) {
        axisYTemp->setRange(tempMin, tempMax);
    }
    if (axisYHumidity) {
        axisYHumidity->setRange(humidityMin, humidityMax);
    }
}

void TH_chart::setAnimationEnabled(bool enabled)
{
    animationEnabled = enabled;
    if (chart) {
        if (enabled) {
            chart->setAnimationOptions(QChart::SeriesAnimations);
        } else {
            chart->setAnimationOptions(QChart::NoAnimation);
        }
    }
}

void TH_chart::updateDisplay()
{
    // 更新标签显示
    if (tempLabel) {
        tempLabel->setText(QString("温度: %1 °C").arg(currentTemp, 0, 'f', 1));
    }
    if (humidityLabel) {
        humidityLabel->setText(QString("湿度: %1 %").arg(currentHumidity, 0, 'f', 1));
    }
    
    // 更新图表数据
    if (tempSeries && humiditySeries) {
        tempSeries->clear();
        humiditySeries->clear();
        
        for (int i = 0; i < tempData.size(); ++i) {
            tempSeries->append(i, tempData[i].y());
        }
        
        for (int i = 0; i < humidityData.size(); ++i) {
            humiditySeries->append(i, humidityData[i].y());
        }
        
        // 更新X轴范围
        if (axisX && tempData.size() > 1) {
            int maxPoints = qMax(tempData.size(), humidityData.size());
            axisX->setRange(0, maxPoints);
        }
    }
}

void TH_chart::updateAnimation()
{
    if (!animationEnabled || !chart) return;
    
    animationProgress += 0.01f;
    if (animationProgress > 1.0f) {
        animationProgress = 0.0f;
    }
    
    // 简单的标题颜色动画
    try {
        float alpha = 0.7f + 0.3f * std::sin(animationProgress * 2 * M_PI);
        QColor titleColor = chart->titleBrush().color();
        titleColor.setAlphaF(alpha);
        chart->setTitleBrush(QBrush(titleColor));
    } catch (...) {
        // 忽略动画错误
    }
}

// 尺寸设置方法
void TH_chart::setChartSize(int width, int height)
{
    if (chartView) {
        chartView->setFixedSize(width, height);
    }
    this->setFixedSize(width, height + 80);
}

void TH_chart::setMinimumChartSize(int minWidth, int minHeight)
{
    if (chartView) {
        chartView->setMinimumSize(minWidth, minHeight);
    }
    this->setMinimumSize(minWidth, minHeight + 60);
}

void TH_chart::setFixedChartSize(int width, int height)
{
    setChartSize(width, height);
}
